﻿#region

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

#endregion

namespace XXS.Common
{
    public static class StringStaticExt
    {

        public static DateTime? ParseToNullableDateTime(this string source)
        {
            DateTime res;
            if (DateTime.TryParse(source, out res))
                return res;

            return null;
        }

        public static int ParseToInt(this string source, int defalut = 0)
        {
            int res = defalut;
            int.TryParse(source, out res);
            return res;
        }

        public static int? ParseToNullableInt(this string source)
        {
            int res;
            if (int.TryParse(source, out res))
                return res;

            return null;
        }

        /// <summary>
        ///     将数据按照分隔符连接成字符串
        /// </summary>
        /// <param name="source"></param>
        /// <param name="spliter"></param>
        /// <param name="removeEmpty"></param>
        /// <returns></returns>
        public static string ToJoinWith(this IEnumerable<string> source, string spliter = ",", bool removeEmpty = true)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));

            var fixedSource = removeEmpty ? source.Where(n => n.IsNotNullAndNotEmpty()).ToList() : source.ToList();

            return fixedSource.Count == 0
                ? string.Empty
                : fixedSource.Aggregate((result, item) => result + $"{spliter}{item}");
        }

        /// <summary>
        ///     string.Format的简便方式
        /// </summary>
        /// <param name="source"></param>
        /// <param name="arguments"></param>
        /// <returns></returns>
        public static string ToFormat(this string source, params object[] arguments)
        {
            return string.Format(source, arguments);
        }

        /// <summary>
        ///     将数据按照分隔符连接成字符串
        /// </summary>
        /// <param name="source"></param>
        /// <param name="spliter"></param>
        /// <returns></returns>
        public static string ToJoinWith(this IEnumerable<char> source, string spliter = ",")
        {
            return source.Select(n => n.ToString()).ToJoinWith(spliter);
        }

        /// <summary>
        ///     将数据按照分隔符连接成字符串
        /// </summary>
        /// <param name="source"></param>
        /// <param name="spliter"></param>
        /// <returns></returns>
        public static string ToJoinWith<T>(this IEnumerable<T> source, Func<T, string> stringCoventer,
            string spliter = ",")
        {
            return source.Select(stringCoventer).ToJoinWith(spliter);
        }

        /// <summary>
        ///     是null或空时,返回真,否则返回假
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool IsNullOrEmpty(this string source)
        {
            return string.IsNullOrEmpty(source);
        }

        /// <summary>
        ///     不是null同时也不是空时,返回真,否则返回假
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool IsNotNullAndNotEmpty(this string source)
        {
            return !string.IsNullOrEmpty(source);
        }

        /// <summary>
        ///     去掉 HTML 标签
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string ToText(this string source)
        {
            if (string.IsNullOrEmpty(source))
                return string.Empty;

            var regex = new[]
            {
                "<[^>]*?>", " ", "　", "&nbsp;", "&gt;", "&lt;", "\\n?\\r??", "&ldquo;", "&middot;", "&rdquo;",
                "&mdash;", "&quot;", "&#8220;", "&#8221;"
            };

            while (regex.Any(n => source.Contains(n)))
            {
                regex.ToList().ForEach(n =>
                {
                    var r = new Regex(n, RegexOptions.IgnoreCase | RegexOptions.Multiline);
                    source = r.Replace(source, string.Empty);
                });
            }

            return source.Trim();
        }

        /// <summary>
        ///     去掉换行符
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string ToSingleLineText(this string source)
        {
            if (string.IsNullOrEmpty(source))
                return string.Empty;

            var regex = new[]
            {
               "\\r\\n", "\\n\\r", Environment.NewLine, "\\r","\\n",
            };

            while (regex.Any(n => source.Contains(n)))
            {
                regex.ToList().ForEach(n =>
                {
                    var r = new Regex(n, RegexOptions.IgnoreCase | RegexOptions.Multiline);
                    source = r.Replace(source, string.Empty);
                });
            }

            return source.Trim();
        }

        public static string ToUnicodeString(this string source)
        {
            if (string.IsNullOrEmpty(source))
                return string.Empty;

            var res = new StringBuilder();

            foreach (var c in source)
            {
                if ((int)c > 32 && (int)c < 127)
                {
                    res.Append(c.ToString());
                }
                else
                    res.Append($"\\u{(int)c:x4}");
            }

            return res.ToString();
        }

        public static string ToInsertSpliter(this string source, string spliter, int everyIndex)
        {
            var res = string.Empty;

            for (var i = 0; i < source.Length; i++)
            {
                res += source[i];
                if ((i + 1) % everyIndex == 0 && i > 0)
                    res += spliter;
            }

            return res;
        }

        public static string ToRelativePath(this string source)
        {
            return source.ToRelativePath(@"/");
        }

        public static string ToRelativePath(this string source, string spliter)
        {
            HttpServerUtility Server = HttpContext.Current.Server;
            string _base = Server.MapPath(@"~/");
            if (source.IndexOf(_base, StringComparison.Ordinal) == -1)
                return source;
            return
                $@"~/{source.Replace(Server.MapPath(@"~/"), "")}".Replace(@"/", spliter).Replace(@"\", spliter);
        }
    }
}